<!DOCTYPE html>
<html lang="en" >
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="author" content="GoJun" />
	
	
	
	<title>Flutter 如何实现国际化多语言 ｜ GoJun</title>
	
    
    
    <meta name="description" content="关于 Flutter 国际化实现方案，网上查看了很多资料，主要有两种。 基于 intl package 的国际化实现（官方推荐） 创建支持语种的 Json 文件，存储及读取里面的语言 本文介绍的是第一种实现方案，毕竟都是官方推荐使用的。 前言 采用第一种方案，" />
    

    
    
    <meta name="keywords" content="Hugo, theme, zozo" />
    

	
    
    <link rel="shortcut icon" href="https://gojun.me/images/favicon.ico" />

    <link rel="stylesheet" type="text/css" media="screen" href="https://gojun.mecss/normalize.css" />
    <link rel="stylesheet" type="text/css" media="screen" href="https://cdn.jsdelivr.net/npm/animate.css@4.1.0/animate.min.css" />
    <link rel="stylesheet" type="text/css" media="screen" href="https://gojun.me/css/zozo.css" />
	<link rel="stylesheet" type="text/css" media="screen" href="https://cdn.jsdelivr.net/npm/remixicon@2.5.0/fonts/remixicon.css" />
    <link rel="stylesheet" type="text/css" media="screen" href="https://gojun.me/css/highlight.css" />

    
    
</head>

<body>
    <div class="main animate__animated animate__fadeInDown">
        <div class="nav_container animated fadeInDown">
    <div class="site_nav" id="site_nav">
        <ul>
            
            <li>
                <a href="/">Home</a>
            </li>
            
            <li>
                <a href="/posts/">Archive</a>
            </li>
            
            <li>
                <a href="/tags/">Tags</a>
            </li>
            
            <li>
                <a href="/projects/">Projects</a>
            </li>
            
        </ul>
    </div>
    <div class="menu_icon">
        <a id="menu_icon"><i class="ri-menu-line"></i></a>
    </div>
</div>
        <div class="header animated fadeInDown">
    <div class="site_title_container">
        <div class="site_title">
            <h1>
                <a href="https://gojun.me">
                    <span>GoJun</span>
                </a>
            </h1>
        </div>
        <div class="description">
            <p class="sub_title">为向往生活努力奋斗！</p>
            <div class="my_socials">
                
                
                <a href="https://github.com/freelander" title="github" target="_blank"><i class="ri-github-fill"></i></a>
                
                
                <a href="https://gojun.me/index.xml" type="application/rss+xml" title="rss" target="_blank"><i
                        class="ri-rss-fill"></i></a>
            </div>
        </div>
    </div>
</div>
        <div class="content">
            <div class="post_page">
                <div class="post animate__animated animate__fadeInDown">
                    <div class="post_title post_detail_title">
                        <h2><a href='/posts/flutter-language/'>Flutter 如何实现国际化多语言</a></h2>
                        <span class="date">2020.02.18</span>
                    </div>
                    <div class="post_content markdown"><p>关于 Flutter 国际化实现方案，网上查看了很多资料，主要有两种。</p>
<ol>
<li>基于 intl package 的国际化实现（官方推荐）</li>
<li>创建支持语种的 Json 文件，存储及读取里面的语言</li>
</ol>
<blockquote>
<p>本文介绍的是第一种实现方案，毕竟都是官方推荐使用的。</p>
</blockquote>
<h3 id="前言">前言</h3>
<p>采用第一种方案，不得不提的一个插件 <a href="https://plugins.jetbrains.com/plugin/13666-flutter-intl/">Flutter Intl</a>，安装使用该插件之后实现国际化非常简单。</p>
<ul>
<li>该插件更新维护频率高，也是目前大部分人使用的。</li>
<li>并且支持 Android Studio 和 VS Code 开发工具</li>
</ul>
<p>下面是以 Android Studio 为例，详细讲解使用过程：</p>
<h3 id="1安装插件">1.安装插件</h3>
<p>在 Preferences &gt; Plugins &gt; Marketplace &gt; 搜索 <code>Flutter Intl</code> &gt; 安装完重启 AS</p>
<p>

<div class="fancybox">
<a data-fancybox="demo" href="/images/2020/02/flutter_language_01.png">
<img src="/images/2020/02/flutter_language_01.png" alt="image"  />
</a>
</div>

</p>
<h3 id="2-初始化项目-intl">2. 初始化项目 Intl</h3>
<p>

<div class="fancybox">
<a data-fancybox="demo" href="/images/2020/02/flutter_language_02.png">
<img src="/images/2020/02/flutter_language_02.png" alt="image"  />
</a>
</div>

</p>
<p>完成上面操作之后会自动生成以下文件目录：</p>
<p>

<div class="fancybox">
<a data-fancybox="demo" href="/images/2020/02/flutter_language_03.png">
<img src="/images/2020/02/flutter_language_03.png" alt="image"  />
</a>
</div>

</p>
<ul>
<li>generated 是自动生成的 dart 代码。</li>
<li>I10n 是对应的 arb 文件目录，项目的文案都是在这里新增。</li>
</ul>
<p>在 <code>pubspec.yaml</code> 文件底部也会新增配置：</p>
<div class="highlight"><pre class="chroma"><code class="language-fallback" data-lang="fallback">flutter_intl:
  enabled: true
</code></pre></div><h3 id="3-项目增加国际化支持">3. 项目增加国际化支持</h3>
<p>在项目的 <code>pubspec.yaml</code> 下添加依赖 <code>flutter_localizations</code></p>
<div class="highlight"><pre class="chroma"><code class="language-dart" data-lang="dart"><span class="nl">dependencies:</span>
  <span class="nl">flutter:</span>
    <span class="nl">sdk:</span> <span class="n">flutter</span>
  <span class="nl">flutter_localizations:</span>
    <span class="nl">sdk:</span> <span class="n">flutter</span>
</code></pre></div><p>添加完之后执行下命令 <code>flutter pub get</code>，回到 <code>main.dart</code> 文件配置项目支持的语种</p>
<div class="highlight"><pre class="chroma"><code class="language-dart" data-lang="dart"><span class="n">runApp</span><span class="p">(</span><span class="n">MaterialApp</span><span class="p">(</span>
    <span class="nl">localizationsDelegates:</span> <span class="p">[</span>
      <span class="n">S</span><span class="p">.</span><span class="n">delegate</span><span class="p">,</span>
      <span class="n">GlobalMaterialLocalizations</span><span class="p">.</span><span class="n">delegate</span><span class="p">,</span>
      <span class="n">GlobalWidgetsLocalizations</span><span class="p">.</span><span class="n">delegate</span><span class="p">,</span>
      <span class="n">GlobalCupertinoLocalizations</span><span class="p">.</span><span class="n">delegate</span><span class="p">,</span>
    <span class="p">],</span>
    <span class="c1">// 支持语种
</span><span class="c1"></span>    <span class="nl">supportedLocales:</span> <span class="n">S</span><span class="p">.</span><span class="n">delegate</span><span class="p">.</span><span class="n">supportedLocales</span><span class="p">,</span>
    <span class="c1">// 设置当前项目的语言
</span><span class="c1"></span>    <span class="nl">locale:</span> <span class="n">Local</span><span class="p">(</span><span class="s1">&#39;en&#39;</span><span class="p">,</span> <span class="s1">&#39;GB&#39;</span><span class="p">),</span>
<span class="p">));</span>
</code></pre></div><p>在主入口前初始化框架当前语言：</p>
<div class="highlight"><pre class="chroma"><code class="language-dart" data-lang="dart"><span class="n">S</span><span class="p">.</span><span class="n">load</span><span class="p">(</span><span class="n">Locale</span><span class="p">(</span><span class="s1">&#39;en&#39;</span><span class="p">,</span> <span class="s1">&#39;GB&#39;</span><span class="p">));</span>
</code></pre></div><h3 id="4-如何使用">4. 如何使用</h3>
<p>在刚通过插件生成的文件 <code>intl_en.arb</code> 下，新增文案：</p>
<div class="highlight"><pre class="chroma"><code class="language-fallback" data-lang="fallback">{
  &#34;contactUs&#34;: &#34;ContactUs&#34;
}
</code></pre></div><p>添加完之后 <code>command+s</code> 保存，插件就会执行命令，在 <code>I10n.dart</code> 和 <code>messages_en.dart</code> 文件下生成对应的代码。</p>
<p>I10n.dart:</p>
<div class="highlight"><pre class="chroma"><code class="language-mysql" data-lang="mysql"><span class="n">class</span><span class="w"> </span><span class="n">S</span><span class="w"> </span><span class="err">{</span><span class="w">
</span><span class="w">  </span><span class="p">...</span><span class="w">
</span><span class="w">
</span><span class="w">  </span><span class="o">///</span><span class="w"> </span><span class="o">`</span><span class="n">ContactUs</span><span class="o">`</span><span class="w">
</span><span class="w">  </span><span class="n">String</span><span class="w"> </span><span class="n">get</span><span class="w"> </span><span class="n">contactUs</span><span class="w"> </span><span class="err">{</span><span class="w">
</span><span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="n">Intl</span><span class="p">.</span><span class="nf">message</span><span class="p">(</span><span class="w">
</span><span class="w">      </span><span class="s1">&#39;ContactUs&#39;</span><span class="p">,</span><span class="w">
</span><span class="w">      </span><span class="n">name</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;contactUs&#39;</span><span class="p">,</span><span class="w">
</span><span class="w">      </span><span class="k">desc</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;&#39;</span><span class="p">,</span><span class="w">
</span><span class="w">      </span><span class="n">args</span><span class="p">:</span><span class="w"> </span><span class="p">[],</span><span class="w">
</span><span class="w">    </span><span class="p">);</span><span class="w">
</span><span class="w">  </span><span class="err">}</span><span class="w">
</span><span class="w"></span><span class="err">}</span><span class="w">
</span></code></pre></div><p>messages_en.dart:</p>
<div class="highlight"><pre class="chroma"><code class="language-fallback" data-lang="fallback">class MessageLookup extends MessageLookupByLibrary {
  String get localeName =&gt; &#39;en&#39;;

  final messages = _notInlinedMessages(_notInlinedMessages);
  static _notInlinedMessages(_) =&gt; &lt;String, Function&gt; {
    &#34;contactUs&#34; : MessageLookupByLibrary.simpleMessage(&#34;ContactUs&#34;)
  };
}
</code></pre></div><p><strong>在代码中使用新增文案</strong></p>
<div class="highlight"><pre class="chroma"><code class="language-fallback" data-lang="fallback">S.of(context).contactUs
</code></pre></div><h3 id="5-如何新增语种">5. 如何新增语种</h3>
<blockquote>
<p>点击 Tools &gt; Flutter Intl &gt; Add Locale</p>
</blockquote>
<p>

<div class="fancybox">
<a data-fancybox="demo" href="/images/2020/02/flutter_language_04.png">
<img src="/images/2020/02/flutter_language_04.png" alt="image"  />
</a>
</div>

</p>
<p>新增 中东阿拉伯语：</p>
<p>

<div class="fancybox">
<a data-fancybox="demo" href="/images/2020/02/flutter_language_05.png">
<img src="/images/2020/02/flutter_language_05.png" alt="image"  />
</a>
</div>

</p>
<p>点击 OK 之后，插件会新创建两个文件：</p>
<p>

<div class="fancybox">
<a data-fancybox="demo" href="/images/2020/02/flutter_language_06.png">
<img src="/images/2020/02/flutter_language_06.png" alt="image"  />
</a>
</div>

</p>
<p>然后在新创建的 <code>intl_ar.arb</code> 文件，增加对应的语种即可：</p>
<div class="highlight"><pre class="chroma"><code class="language-fallback" data-lang="fallback">{
  &#34;contactUs&#34;: &#34;اتصل بنا&#34;
}
</code></pre></div><h3 id="6-arb-文件更多语法使用">6. Arb 文件更多语法使用</h3>
<p>占位符：</p>
<div class="highlight"><pre class="chroma"><code class="language-fallback" data-lang="fallback">{
    &#34;hello&#34;: &#34;Hello {name}&#34;
}
</code></pre></div><p>使用：</p>
<div class="highlight"><pre class="chroma"><code class="language-fallback" data-lang="fallback">S.of(contxt).hello(&#34;GoJun&#34;);
</code></pre></div><h3 id="资料">资料</h3>
<ul>
<li><a href="https://www.jianshu.com/p/1960d34e54ae">Flutter国际化的三种方式&ndash;&gt;json</a></li>
<li><a href="https://flutter.dev/docs/development/accessibility-and-localization/internationalization">官方文档 Flutter 应用国际化</a></li>
<li><a href="https://plugins.jetbrains.com/plugin/13666-flutter-intl/">Fluter Intl 插件</a></li>
</ul>
</div>
                    <div class="post_footer">
                        
                        <div class="meta">
                            <div class="info">
                                <span class="field tags">
                                    <i class="ri-stack-line"></i>
                                    
                                    <a href="https://gojun.me/tags/flutter/">Flutter</a>
                                    
                                </span>
                            </div>
                        </div>
                        
                    </div>
                </div>
                
                
                <div class="doc_comments"></div>
                
            </div>
        </div>
    </div>
    <a id="back_to_top" href="#" class="back_to_top"><i class="ri-arrow-up-s-line"></i></a>
    <footer class="footer">
    <div class="footer_slogan">
        <span></span>
    </div>
</footer>
    <script src="https://gojun.me/js/jquery-3.5.1.min.js"></script>
<link href="https://gojun.me/css/fancybox.min.css" rel="stylesheet">
<script src="https://gojun.me/js/fancybox.min.js"></script>
<script src="https://gojun.me/js/zozo.js"></script>


<script type="text/javascript" async
    src="https://cdn.bootcss.com/mathjax/2.7.5/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
        MathJax.Hub.Config({
            tex2jax: {
                inlineMath: [['$', '$'], ['\\(', '\\)']],
                displayMath: [['$$', '$$'], ['\[\[', '\]\]']],
                processEscapes: true,
                processEnvironments: true,
                skipTags: ['script', 'noscript', 'style', 'textarea', 'pre'],
                TeX: {
                    equationNumbers: { autoNumber: "AMS" },
                    extensions: ["AMSmath.js", "AMSsymbols.js"]
                }
            }
        });

        MathJax.Hub.Queue(function () {
            
            
            
            var all = MathJax.Hub.getAllJax(), i;
            for (i = 0; i < all.length; i += 1) {
                all[i].SourceElement().parentNode.className += ' has-jax';
            }
        });
    </script>

<style>
    code.has-jax {
        font: inherit;
        font-size: 100%;
        background: inherit;
        border: inherit;
        color: #515151;
    }
</style>



<script type="application/javascript">
var doNotTrack = false;
if (!doNotTrack) {
	window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
	ga('create', 'UA-142037913-1', 'auto');
	
	ga('send', 'pageview');
}
</script>
<script async src='https://www.google-analytics.com/analytics.js'></script>

</body>

</html>